package fm.dongman.animefm.view.widget

import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import android.widget.FrameLayout
import android.view.animation.AlphaAnimation
import android.view.LayoutInflater
import android.view.ViewStub
import android.view.ViewGroup
import android.view.View
import fm.dongman.animefm.R
import org.jetbrains.anko.onClick


/**
 * 多状态布局控件
 * 对于空数据和网络错误的状态提供了重试接口，
 * 需要在空数据或网络错误布局中指定触发的view对应的id：
 * android:id="@id/id_sfl_empty_retry"或android:id="@id/id_sfl_net_error_retry"
 * Created by shize on 2017/10/27.
 */
class MultiStateLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, def: Int = 0)
    : FrameLayout(context, attrs, def) {

    companion object{
        /*初始状态，不显示任何View*/
        val INIT = 0X1
        /*请求数据*/
        val LOADING = 0X2
        /*空数据*/
        val EMPTY = 0X3
        /*网络异常*/
        val NET_ERROR = 0X4
        /*正常显示*/
        val SUCCESS = 0X5
    }

    /*Loading视图布局id*/
    private var mLoadingLayoutId = -1
    /*Empty视图布局id*/
    private var mEmptyLayoutId = -1
    /*NetError视图布局id*/
    private var mNetErrorLayoutId = -1
    /*Loading视图*/
    private var mVsLoading: ViewStub? = null
    private var mLoadingView: View? = null
    /*Empty视图*/
    private var mVsEmpty: ViewStub? = null
    private var mEmptyView: View? = null
    /*NetError视图*/
    private var mVsNetError: ViewStub? = null
    private var mNetErrorView: View? = null
    /*内容视图*/
    private var mContentView: View? = null
    /*内容视图显示动画*/
    private var mEnableContentAnim = true
    /*当前状态*/
    private var mCurState: Int = 0
    /*重试监听*/
    private var mEmptyRetryListener: OnEmptyRetryListener? = null
    private var mNetErrorRetryListener: OnNetErrorRetryListener? = null
    private var mHasInit = false

    init {
        layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        //获取自定义属性
        val ta: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.MultiStateLayout)
        (0..ta.indexCount - 1)
                .map { ta.getIndex(it) }
                .forEach {
                    when (it) {
                        R.styleable.MultiStateLayout_loadingLayoutResId -> {
                            mLoadingLayoutId = ta.getResourceId(it, -1)
                        }
                        R.styleable.MultiStateLayout_emptyLayoutResId -> {
                            mEmptyLayoutId = ta.getResourceId(it, -1)
                        }
                        R.styleable.MultiStateLayout_netErrorLayoutResId -> {
                            mNetErrorLayoutId = ta.getResourceId(it, -1)
                        }
                        R.styleable.MultiStateLayout_enableContentAnim -> {
                            mEnableContentAnim = ta.getBoolean(it, true)
                        }
                    }
                }
        ta.recycle()
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        if (!mHasInit) {
            //初始化
            if (mContentView == null) {
                if (childCount > 0)
                    mContentView = getChildAt(0)
            }
            if (mLoadingLayoutId != -1) {
                mVsLoading = ViewStub(context)
                mVsLoading!!.layoutResource = mLoadingLayoutId
                addView(mVsLoading)
            }
            if (mEmptyLayoutId != -1) {
                mVsEmpty = ViewStub(context)
                mVsEmpty!!.layoutResource = mEmptyLayoutId
                addView(mVsEmpty)
            }
            if (mNetErrorLayoutId != -1) {
                mVsNetError = ViewStub(context)
                mVsNetError!!.layoutResource = mNetErrorLayoutId
                addView(mVsNetError)
            }
            //切换到初始状态
            changeState(INIT)
            mHasInit = true
        }
    }

    /**
     * 切换状态

     * @param state 状态标识
     */
    fun changeState(state: Int) {
        if (mCurState == state)
            return
        hideAllViews()
        when (state) {
            LOADING -> {
                checkLoadingView()
            }
            EMPTY -> {
                checkEmptyView()
            }
            NET_ERROR -> {
                checkNetErrorView()
            }
            SUCCESS -> {
                checkContentView()
            }
        }
        mCurState = state
    }

    /*隐藏所有布局*/
    private fun hideAllViews() {
        mLoadingView?.visibility = View.GONE
        mEmptyView?.visibility = View.GONE
        mNetErrorView?.visibility = View.GONE
        mContentView?.visibility = View.GONE
    }

    /*切换Loading布局*/
    private fun checkLoadingView() {
        if (mLoadingView == null) {
            if (mVsLoading != null)
                mLoadingView = mVsLoading!!.inflate()
            else if (mLoadingLayoutId != -1)
                mLoadingView = LayoutInflater.from(context).inflate(mLoadingLayoutId, this, false)
        }
        if (mLoadingView != null) {
            mLoadingView!!.visibility = View.VISIBLE
        }
    }

    /*切换Empty布局*/
    private fun checkEmptyView() {
        if (mEmptyView == null) {
            if (mVsEmpty != null)
                mEmptyView = mVsEmpty!!.inflate()
            else if (mEmptyLayoutId != -1)
                mEmptyView = LayoutInflater.from(context).inflate(mEmptyLayoutId, this, false)
        }
        if (mEmptyView != null) {
            mEmptyView!!.findViewById(R.id.id_sfl_empty_retry)?.onClick {
                if (mEmptyRetryListener != null)
                    mEmptyRetryListener!!.onEmptyRetry()
            }
            mEmptyView!!.visibility = View.VISIBLE
        }
    }

    /*切换NetError布局*/
    private fun checkNetErrorView() {
        if (mNetErrorView == null) {
            if (mVsNetError != null)
                mNetErrorView = mVsNetError!!.inflate()
            else if (mNetErrorLayoutId != -1)
                mNetErrorView = LayoutInflater.from(context).inflate(mNetErrorLayoutId, this, false)
        }
        if (mNetErrorView != null) {
            mNetErrorView!!.findViewById(R.id.id_sfl_net_error_retry)?.onClick {
                if (mNetErrorRetryListener != null)
                    mNetErrorRetryListener!!.onNetErrorRetry()
            }
            mNetErrorView!!.visibility = View.VISIBLE
        }
    }

    /*切换内容布局*/
    private fun checkContentView() {
        if (mContentView != null) {
            if (mEnableContentAnim) {
                val animation = AlphaAnimation(0f, 1.0f)
                animation.duration = 200
                mContentView!!.startAnimation(animation)
            }
            mContentView!!.visibility = View.VISIBLE
        }
    }

    /**
     * 获取当前状态
     */
    fun getCurrentState(): Int {
        return mCurState
    }

    /**
     * 是否开启内容布局显示动画
     */
    fun enableContentAnim(enable: Boolean) {
        this.mEnableContentAnim = enable
    }

    /**
     * 设置网络错误重试监听

     * @param listener 重试监听
     */
    fun setOnNetErrorRetryListener(listener: OnNetErrorRetryListener) {
        this.mNetErrorRetryListener = listener
    }

    /**
     * 设置空数据重试监听

     * @param listener 重试监听
     */
    fun setOnEmptyRetryListener(listener: OnEmptyRetryListener) {
        this.mEmptyRetryListener = listener
    }

    interface OnNetErrorRetryListener {
        fun onNetErrorRetry()
    }

    interface OnEmptyRetryListener {
        fun onEmptyRetry()
    }
}